﻿#pragma once

#include <learn/ais/ais_curve.h>
#include <learn/ais/ais_frame.h>
#include <learn/ais/ais_mesh.h>
#include <learn/ais/ais_point.h>
#include <learn/ais/ais_point_cloud.h>
#include <learn/ais/ais_surface.h>
#include <learn/ais/ais_vector.h>

namespace xi
{

namespace gl
{

using namespace xi::ais;

// 前向声明
class EXT_SYMBOL GL_Context;

class EXT_SYMBOL GL_Renderer : public AIS_Renderer
{
  protected:
    GL_Context *m_ctx;

  public:
    /**
     * @brief 默认构造函数
     *
     * @param[in] ctx
     */
    GL_Renderer(GL_Context *ctx);

    /**
     * @brief 重载默认析构函数
     *
     */
    ~GL_Renderer() override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;
};

class EXT_SYMBOL GL_PointRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 单点渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_PointRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    Vec3f normalColor{1.0f, 1.0f, 1.0f};
    Vec3f hoveredColor{0.0f, 1.0f, 0.0f};
    Vec3f pressedColor{0.0f, 1.0f, 0.0f};
    float normalOpacity{1.0f};
    float hoveredOpacity{0.6f};
    float pressedOpacity{0.8f};
    std::size_t normalSize{5};
    std::size_t hoveredSize{7};
    std::size_t pressedSize{6};
};

class EXT_SYMBOL GL_PointCloudRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 单点渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_PointCloudRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    Vec3f normalColor{0.0f, 0.0f, 1.0f};
    float normalOpacity{1.0f};
    std::size_t normalSize{5};
};

class EXT_SYMBOL GL_VectorRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 向量渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_VectorRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    float normalOpacity{1.0f};
    float hoveredOpacity{0.6f};
    float pressedOpacity{0.8f};
};

class EXT_SYMBOL GL_CurveRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 曲线渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_CurveRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    std::size_t sampleCount{100};
    Vec3f normalColor{1.0f, 1.0f, 1.0f};
    Vec3f hoveredColor{0.0f, 1.0f, 0.0f};
    Vec3f pressedColor{0.0f, 1.0f, 0.0f};
    float normalOpacity{1.0f};
    float hoveredOpacity{0.6f};
    float pressedOpacity{0.8f};
    std::size_t normalWidth{2};
    std::size_t hoveredWidth{4};
    std::size_t pressedWidth{3};
};

class EXT_SYMBOL GL_MeshRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 网格渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_MeshRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    float normalOpacity{1.0f};
    float hoveredOpacity{0.6f};
    float pressedOpacity{0.8f};
    Vec3f direction{0.0f, 0.0f, -1.0f}; // 光线方向
    Vec3f ambient{0.1f, 0.1f, 0.1f};    // 环境光
    Vec3f diffuse{0.8f, 0.8f, 0.8f};    // 漫反射
    Vec3f specular{0.8f, 0.8f, 0.8f};   // 镜面反射
    int zebra{10};                      // 斑马纹密度
    unsigned int diffuseTex;            // 散射纹理
    unsigned int specularTex;           // 镜面纹理
    unsigned int reflectTex;            // 反射纹理
    unsigned int reflactTex;            // 折射纹理

  protected:
    std::size_t m_count;                           // 记录网格顶点数量
    std::function<Mesh_Data(AIS_Object *)> m_data; // 网格数据获取函数
};

class EXT_SYMBOL GL_SurfaceRenderer : public GL_MeshRenderer
{
  public:
    /**
     * @brief 曲面渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_SurfaceRenderer(GL_Context *ctx);

  public:
    std::size_t sampleCount{30};
};

class EXT_SYMBOL GL_FrameRenderer : public GL_Renderer
{
  public:
    /**
     * @brief 框架渲染器构造函数
     *
     * @param[in] ctx
     */
    GL_FrameRenderer(GL_Context *ctx);

    /**
     * @brief 刷新渲染器
     *
     * @param[in] obj
     */
    void update(AIS_Object *obj) override;

    /**
     * @brief 绘制物体
     *
     * @param[in] obj
     */
    void draw(AIS_Object *obj) const override;

  public:
    float alpha{1.0f}; // 透明度
};

} // namespace gl

} // namespace xi
